/**
 * ----------------------------------------------------------------------------
 * Copyright Jens Konopka
 * 
 * Alle Rechte vorbehalten.
 * Licence: Apache 2.0
 * ----------------------------------------------------------------------------
 *
 * created on 05.03.2012 by jkonopka
 */
package de.sql.toolkit.exporter;

import java.io.File;
import java.io.IOException;
import java.util.List;

import de.sql.toolkit.generator.IGenerator;
import de.sql.toolkit.generator.JvModelFieldsGenerator;
import de.sql.toolkit.generator.JvModelGenerator;
import de.sql.toolkit.generator.JvModelGetterGenerator;
import de.sql.toolkit.generator.JvModelSetterGenerator;
import de.sql.toolkit.generator.JvModelToStringGenerator;
import de.sql.toolkit.model.Table;
import de.sql.toolkit.reader.CreateTableScriptReader;
import de.sql.toolkit.util.FilenameUtil;
import de.sql.toolkit.util.StringUtil;

/**
 * @author jkonopka
 * 
 */
public class JvModelSourceClassExporter extends AbstractExporter {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6408921630239539986L;
	private String namespace;

	/**
	 * @param dstPath
	 * @param schema
	 * @param namespace
	 */
	public JvModelSourceClassExporter(File dstPath, String schema, final String namespace) {
		super(dstPath, schema);
		setNamespace(namespace);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.sql.toolkit.IGenerator#generate()
	 */
	@Override
	public void export() throws Exception {
		validateDstPath();
		final CreateTableScriptReader reader = new CreateTableScriptReader(getSchema());
		final List<Table> list = reader.read();
		for (final Table table : list) {
			final Thread thread = new Thread() {

				/*
				 * (non-Javadoc)
				 * 
				 * @see java.lang.Thread#run()
				 */
				@Override
				public void run() {
					try {
						generate(table);
					} catch (final Exception e) {
						e.printStackTrace();
					}
				}

			};
			thread.start();
		}
	}

	/**
	 * @param table
	 * @throws Exception
	 */
	private void generate(final Table table) throws Exception {
		final IGenerator writer = initWriter(table);
		final String content = writer.generate();
		final String filename = FilenameUtil.concat(createPackagePath(), createFilename(table.getName()));
		writeContentToFile(filename, content);
	}

	/**
	 * @param table
	 * @return
	 */
	protected IGenerator initWriter(final Table table) {
		final JvModelGenerator writer = new JvModelGenerator(getDstPath(), table, getNamespace());
		writer.add(new JvModelFieldsGenerator(getDstPath(), table));
		writer.add(new JvModelSetterGenerator(getDstPath(), table));
		writer.add(new JvModelGetterGenerator(getDstPath(), table));
		writer.add(new JvModelToStringGenerator(getDstPath(), table));
		return writer;
	}

	/**
	 * @param filename
	 * @return
	 */
	private String createFilename(String name) {
		name = name.replaceAll(" ", "");
		name = name.replaceAll("_", "");
		name = name.toLowerCase();
		final String string = StringUtil.upperCaseFirstLetters(name) + "." + getExtension();
		return string;
	}

	/**
	 * @return
	 */
	protected String getExtension() {
		return "java";
	}

	/**
	 * @return
	 * @throws Exception
	 */
	private String createPackagePath() throws Exception {
		final String packagePath = namespace.replace(".", File.separator);
		final File file = getDstPath();
		final File newPath = new File(FilenameUtil.concat(file.getAbsolutePath(), packagePath));
		if (!newPath.exists()) {
			final boolean mkdir = newPath.mkdir();
			if (!mkdir) {
				throw new IOException(String.format("can not create the path %s.", newPath.getAbsolutePath()));
			}
		}
		return newPath.getAbsolutePath();
	}

	/**
	 * @return the namespace
	 */
	protected final String getNamespace() {
		return namespace;
	}

	/**
	 * @param namespace the namespace to set
	 */
	protected final void setNamespace(String namespace) {
		this.namespace = namespace;
	}

}
